import { v2 } from 'cc';
import { _decorator, Component, Node, Sprite, SpriteFrame, ScrollView, Layout, UITransform, EventHandler } from 'cc';
const { ccclass, property, menu } = _decorator;

@ccclass('TabController')
@menu('UI/TabController')
export class TabController extends Component {

    @property({
        type: ScrollView,
        tooltip: "包含Tab按钮的ScrollView组件"
    })
    scrollView: ScrollView = null!;

    @property({
        type: Node,
        tooltip: "Tab按钮容器节点"
    })
    tabContainer: Node = null!;

    @property({
        type: [Node],
        tooltip: "Tab按钮节点数组"
    })
    tabButtons: Node[] = [];

    @property({
        type: [Node],
        tooltip: "对应Tab内容节点数组"
    })
    tabContents: Node[] = [];

    @property({
        type: [SpriteFrame],
        tooltip: "每个Tab按钮的选中状态背景图(顺序与tabButtons对应)"
    })
    selectedBgs: SpriteFrame[] = [];

    @property({
        type: [SpriteFrame],
        tooltip: "每个Tab按钮的未选中状态背景图(顺序与tabButtons对应)"
    })
    normalBgs: SpriteFrame[] = [];

    @property({
        tooltip: "选中状态的缩放大小"
    })
    selectedScale: number = 1.1;

    @property({
        tooltip: "默认选中的Tab索引"
    })
    defaultIndex: number = 0;

    @property({
        type: EventHandler,
        tooltip: "Tab切换时的事件回调"
    })
    tabChangeEvents: EventHandler[] = [];

    private _selectedIndex: number = -1;
    private _layout: Layout = null!;

    protected onLoad() {
        // 检查配置是否正确
        if (!this.scrollView) {
            console.error("未设置ScrollView组件");
            return;
        }

        if (!this.tabContainer) {
            console.error("未设置Tab按钮容器节点");
            return;
        }

        if (this.tabButtons.length !== this.tabContents.length) {
            console.error("Tab按钮和内容数量不匹配");
            return;
        }

        if (this.tabButtons.length !== this.selectedBgs.length || this.tabButtons.length !== this.normalBgs.length) {
            console.error("Tab按钮和状态图片数量不匹配");
            return;
        }

        // 获取Layout组件
        this._layout = this.tabContainer.getComponent(Layout)!;
        if (!this._layout) {
            console.warn("Tab按钮容器没有Layout组件，将添加默认水平布局");
            this._layout = this.tabContainer.addComponent(Layout);
            this._layout.type = Layout.Type.HORIZONTAL;
            this._layout.spacingX = 10;
            this._layout.resizeMode = Layout.ResizeMode.CONTAINER;
        }

        // 初始化Tab按钮
        this.tabButtons.forEach((btn, index) => {
            btn.on(Node.EventType.TOUCH_END, () => {
                this.selectTab(index);
                this.scrollToTab(index);
            });
        });

        // 设置默认选中
        this.selectTab(this.defaultIndex);
    }

    /**
     * 选择指定索引的Tab
     * @param index Tab索引
     */
    selectTab(index: number) {
        if (index === this._selectedIndex || index < 0 || index >= this.tabButtons.length) {
            return;
        }

        // 取消之前选中的Tab
        if (this._selectedIndex >= 0) {
            this.deselectTab(this._selectedIndex);
        }

        // 设置新的选中Tab
        this._selectedIndex = index;
        this.activateTab(index);

        // 触发切换事件
        EventHandler.emitEvents(this.tabChangeEvents, index);
    }

    /**
     * 激活指定Tab
     * @param index Tab索引
     */
    private activateTab(index: number) {
        const btn = this.tabButtons[index];
        const content = this.tabContents[index];

        // 按钮状态变化 - 使用独立的选中图片
        const sprite = btn.getComponent(Sprite);
        if (sprite && this.selectedBgs[index]) {
            sprite.spriteFrame = this.selectedBgs[index];
        }

        // 按钮大小变化
        btn.setScale(this.selectedScale, this.selectedScale);

        // 内容显示
        content.active = true;
    }

    /**
     * 取消选中指定Tab
     * @param index Tab索引
     */
    private deselectTab(index: number) {
        const btn = this.tabButtons[index];
        const content = this.tabContents[index];

        // 按钮状态变化 - 使用独立的未选中图片
        const sprite = btn.getComponent(Sprite);
        if (sprite && this.normalBgs[index]) {
            sprite.spriteFrame = this.normalBgs[index];
        }

        // 按钮大小变化
        btn.setScale(1, 1);

        // 内容隐藏
        content.active = false;
    }

    /**
     * 滚动到指定Tab位置
     * @param index Tab索引
     */
    private scrollToTab(index: number) {
        if (!this.scrollView || index < 0 || index >= this.tabButtons.length) {
            return;
        }

        const btn = this.tabButtons[index];
        const btnWorldPos = btn.getWorldPosition();
        const containerWorldPos = this.tabContainer.getWorldPosition();
        const scrollViewNode = this.scrollView.node!;

        // 计算按钮在ScrollView中的位置
        const localPos = scrollViewNode.getComponent(UITransform)!.convertToNodeSpaceAR(btnWorldPos);
        const containerLocalPos = scrollViewNode.getComponent(UITransform)!.convertToNodeSpaceAR(containerWorldPos);

        // 计算滚动位置
        const scrollViewWidth = scrollViewNode.getComponent(UITransform)!.width;
        const btnWidth = btn.getComponent(UITransform)!.width * this.selectedScale;
        const btnLeft = localPos.x - btnWidth / 2;
        const btnRight = localPos.x + btnWidth / 2;

        // 当前滚动位置
        const currentScrollPos = this.scrollView.getScrollOffset().x;

        // 计算需要的滚动位置
        let targetScrollPos = 0;
        if (btnLeft < 0) {
            // 按钮在左侧边界外
            targetScrollPos = currentScrollPos + btnLeft;
        } else if (btnRight > scrollViewWidth) {
            // 按钮在右侧边界外
            targetScrollPos = currentScrollPos + (btnRight - scrollViewWidth);
        } else {
            return; // 按钮已经在可见区域内
        }

        // 限制滚动范围
        const maxScrollPos = this.scrollView.getMaxScrollOffset().x;
        targetScrollPos = Math.max(0, Math.min(targetScrollPos, maxScrollPos));

        // 设置滚动位置
        this.scrollView.scrollToOffset(v2(targetScrollPos, 0), 0.3);
    }

    /**
     * 获取当前选中的Tab索引
     */
    get selectedIndex(): number {
        return this._selectedIndex;
    }

    /**
     * 通过代码切换Tab
     * @param index Tab索引
     */
    public switchToTab(index: number) {
        this.selectTab(index);
        this.scrollToTab(index);
    }
}